Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Displaying Raw • Download


Examples/Request.py 72db6e0ef2e9da96b5f164eb7c37ddbf3022bdec (72db6e0e) Text, 9.29 KB

T8b949e##########################################################
T8b949e# This RNS example demonstrates how to perform requests #
T8b949e# and receive responses over a link. #
T8b949e##########################################################

Tff7b72import T7ee787os
Tff7b72import T7ee787sys
Tff7b72import T7ee787time
Tff7b72import T7ee787random
Tff7b72import T7ee787argparse
Tff7b72import T7ee787RNS

T8b949e# Let's define an app name. We'll use this for all
T8b949e# destinations we create. Since this echo example
T8b949e# is part of a range of example utilities, we'll put
T8b949e# them all within the app namespace "example_utilities"
Te6edf3APP_NAME Tff7b72= Ta5d6ff"Ta5d6ffexample_utilitiesTa5d6ff"

T8b949e##########################################################
T8b949e#### Server Part #########################################
T8b949e##########################################################

T8b949e# A reference to the latest client link that connected
Te6edf3latest_client_link Tff7b72= Tff7b72None

Tff7b72def Td2a8ffrandom_text_generatorTb4b4b4(Te6edf3pathTb4b4b4, Te6edf3dataTb4b4b4, Te6edf3request_idTb4b4b4, Te6edf3link_idTb4b4b4, Te6edf3remote_identityTb4b4b4, Te6edf3requested_atTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffGenerating response to request Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3request_idTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff on link Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3link_idTb4b4b4)Tb4b4b4)
Te6edf3texts Tff7b72= Tb4b4b4[Ta5d6ff"Ta5d6ffThey looked upTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffOn each full moonTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffBecky was upsetTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffI’ll stay away from itTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffThe pet shop stocks everythingTa5d6ff"Tb4b4b4]
Tff7b72return Te6edf3textsTb4b4b4[Te6edf3randomTff7b72.Td2a8ffrandintTb4b4b4(T79c0ff0Tb4b4b4, Tffa657lenTb4b4b4(Te6edf3textsTb4b4b4)Tff7b72-T79c0ff1Tb4b4b4)Tb4b4b4]

T8b949e# This initialisation is executed when the users chooses
T8b949e# to run as a server
Tff7b72def Td2a8ffserverTb4b4b4(Te6edf3configpathTb4b4b4)Tb4b4b4:
T8b949e# We must first initialise Reticulum
Te6edf3reticulum Tff7b72= Te6edf3RNSTff7b72.Td2a8ffReticulumTb4b4b4(Te6edf3configpathTb4b4b4)
T8b949e# Randomly create a new identity for our link example
Te6edf3server_identity Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTb4b4b4(Tb4b4b4)

T8b949e# We create a destination that clients can connect to. We
T8b949e# want clients to create links to this destination, so we
T8b949e# need to create a "single" destination type.
Te6edf3server_destination Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTb4b4b4(
Te6edf3server_identityTb4b4b4,
Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffINTb4b4b4,
Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffSINGLETb4b4b4,
Te6edf3APP_NAMETb4b4b4,
Ta5d6ff"Ta5d6ffrequestexampleTa5d6ff"
Tb4b4b4)

T8b949e# We configure a function that will get called every time
T8b949e# a new client creates a link to this destination.
Te6edf3server_destinationTff7b72.Td2a8ffset_link_established_callbackTb4b4b4(Te6edf3client_connectedTb4b4b4)

T8b949e# We register a request handler for handling incoming
T8b949e# requests over any established links.
Te6edf3server_destinationTff7b72.Td2a8ffregister_request_handlerTb4b4b4(
Ta5d6ff"Ta5d6ff/random/textTa5d6ff"Tb4b4b4,
Te6edf3response_generator Tff7b72= Te6edf3random_text_generatorTb4b4b4,
Te6edf3allow Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffALLOW_ALL
Tb4b4b4)

T8b949e# Everything's ready!
T8b949e# Let's Wait for client requests or user input
Te6edf3server_loopTb4b4b4(Te6edf3server_destinationTb4b4b4)

Tff7b72def Td2a8ffserver_loopTb4b4b4(Te6edf3destinationTb4b4b4)Tb4b4b4:
T8b949e# Let the user know that everything is ready
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(
Ta5d6ff"Ta5d6ffRequest example Ta5d6ff"Tff7b72+
Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3destinationTff7b72.Td2a8ffhashTb4b4b4)Tff7b72+
Ta5d6ff"Ta5d6ff running, waiting for a connection.Ta5d6ff"
Tb4b4b4)

Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffHit enter to manually send an announce (Ctrl-C to quit)Ta5d6ff"Tb4b4b4)

T8b949e# We enter a loop that runs until the users exits.
T8b949e# If the user hits enter, we will announce our server
T8b949e# destination on the network, which will let clients
T8b949e# know how to create messages directed towards it.
Tff7b72while Tff7b72TrueTb4b4b4:
Te6edf3entered Tff7b72= Tffa657inputTb4b4b4(Tb4b4b4)
Te6edf3destinationTff7b72.Td2a8ffannounceTb4b4b4(Tb4b4b4)
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffSent announce from Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3destinationTff7b72.Td2a8ffhashTb4b4b4)Tb4b4b4)

T8b949e# When a client establishes a link to our server
T8b949e# destination, this function will be called with
T8b949e# a reference to the link.
Tff7b72def Td2a8ffclient_connectedTb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4:
Tff7b72global Te6edf3latest_client_link

Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffClient connectedTa5d6ff"Tb4b4b4)
Te6edf3linkTff7b72.Td2a8ffset_link_closed_callbackTb4b4b4(Te6edf3client_disconnectedTb4b4b4)
Te6edf3latest_client_link Tff7b72= Te6edf3link

Tff7b72def Td2a8ffclient_disconnectedTb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffClient disconnectedTa5d6ff"Tb4b4b4)


T8b949e##########################################################
T8b949e#### Client Part #########################################
T8b949e##########################################################

T8b949e# A reference to the server link
Te6edf3server_link Tff7b72= Tff7b72None

T8b949e# This initialisation is executed when the users chooses
T8b949e# to run as a client
Tff7b72def Td2a8ffclientTb4b4b4(Te6edf3destination_hexhashTb4b4b4, Te6edf3configpathTb4b4b4)Tb4b4b4:
T8b949e# We need a binary representation of the destination
T8b949e# hash that was entered on the command line
Tff7b72tryTb4b4b4:
Te6edf3dest_len Tff7b72= Tb4b4b4(Te6edf3RNSTff7b72.Td2a8ffReticulumTff7b72.Td2a8ffTRUNCATED_HASHLENGTHTff7b72/Tff7b72/T79c0ff8Tb4b4b4)Tff7b72*T79c0ff2
Tff7b72if Tffa657lenTb4b4b4(Te6edf3destination_hexhashTb4b4b4) Tff7b72!= Te6edf3dest_lenTb4b4b4:
Tff7b72raise Tf85149ValueErrorTb4b4b4(
Ta5d6ff"Ta5d6ffDestination length is invalid, must be Tffd700{hex}Ta5d6ff hexadecimal characters (Tffd700{byte}Ta5d6ff bytes).Ta5d6ff"Tff7b72.Td2a8ffformatTb4b4b4(Tffa657hexTff7b72=Te6edf3dest_lenTb4b4b4, Te6edf3byteTff7b72=Te6edf3dest_lenTff7b72/Tff7b72/T79c0ff2Tb4b4b4)
Tb4b4b4)
Te6edf3destination_hash Tff7b72= Tffa657bytesTff7b72.Td2a8fffromhexTb4b4b4(Te6edf3destination_hexhashTb4b4b4)
Tff7b72exceptTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffInvalid destination entered. Check your input!Tffea00\nTa5d6ff"Tb4b4b4)
Te6edf3sysTff7b72.Td2a8ffexitTb4b4b4(T79c0ff0Tb4b4b4)

T8b949e# We must first initialise Reticulum
Te6edf3reticulum Tff7b72= Te6edf3RNSTff7b72.Td2a8ffReticulumTb4b4b4(Te6edf3configpathTb4b4b4)

T8b949e# Check if we know a path to the destination
Tff7b72if Tff7b72not Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffhas_pathTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffDestination is not yet known. Requesting path and waiting for announce to arrive...Ta5d6ff"Tb4b4b4)
Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffrequest_pathTb4b4b4(Te6edf3destination_hashTb4b4b4)
Tff7b72while Tff7b72not Te6edf3RNSTff7b72.Td2a8ffTransportTff7b72.Td2a8ffhas_pathTb4b4b4(Te6edf3destination_hashTb4b4b4)Tb4b4b4:
Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0.1Tb4b4b4)

T8b949e# Recall the server identity
Te6edf3server_identity Tff7b72= Te6edf3RNSTff7b72.Td2a8ffIdentityTff7b72.Td2a8ffrecallTb4b4b4(Te6edf3destination_hashTb4b4b4)

T8b949e# Inform the user that we'll begin connecting
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffEstablishing link with server...Ta5d6ff"Tb4b4b4)

T8b949e# When the server identity is known, we set
T8b949e# up a destination
Te6edf3server_destination Tff7b72= Te6edf3RNSTff7b72.Td2a8ffDestinationTb4b4b4(
Te6edf3server_identityTb4b4b4,
Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffOUTTb4b4b4,
Te6edf3RNSTff7b72.Td2a8ffDestinationTff7b72.Td2a8ffSINGLETb4b4b4,
Te6edf3APP_NAMETb4b4b4,
Ta5d6ff"Ta5d6ffrequestexampleTa5d6ff"
Tb4b4b4)

T8b949e# And create a link
Te6edf3link Tff7b72= Te6edf3RNSTff7b72.Td2a8ffLinkTb4b4b4(Te6edf3server_destinationTb4b4b4)

T8b949e# We'll set up functions to inform the
T8b949e# user when the link is established or closed
Te6edf3linkTff7b72.Td2a8ffset_link_established_callbackTb4b4b4(Te6edf3link_establishedTb4b4b4)
Te6edf3linkTff7b72.Td2a8ffset_link_closed_callbackTb4b4b4(Te6edf3link_closedTb4b4b4)

T8b949e# Everything is set up, so let's enter a loop
T8b949e# for the user to interact with the example
Te6edf3client_loopTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffclient_loopTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72global Te6edf3server_link

T8b949e# Wait for the link to become active
Tff7b72while Tff7b72not Te6edf3server_linkTb4b4b4:
Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff0.1Tb4b4b4)

Te6edf3should_quit Tff7b72= Tff7b72False
Tff7b72while Tff7b72not Te6edf3should_quitTb4b4b4:
Tff7b72tryTb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ff> Ta5d6ff"Tb4b4b4, Te6edf3endTff7b72=Ta5d6ff"Ta5d6ff Ta5d6ff"Tb4b4b4)
Te6edf3text Tff7b72= Tffa657inputTb4b4b4(Tb4b4b4)

T8b949e# Check if we should quit the example
Tff7b72if Te6edf3text Tff7b72== Ta5d6ff"Ta5d6ffquitTa5d6ff" Tff7b72or Te6edf3text Tff7b72== Ta5d6ff"Ta5d6ffqTa5d6ff" Tff7b72or Te6edf3text Tff7b72== Ta5d6ff"Ta5d6ffexitTa5d6ff"Tb4b4b4:
Te6edf3should_quit Tff7b72= Tff7b72True
Te6edf3server_linkTff7b72.Td2a8ffteardownTb4b4b4(Tb4b4b4)

Tff7b72elseTb4b4b4:
Te6edf3server_linkTff7b72.Td2a8ffrequestTb4b4b4(
Ta5d6ff"Ta5d6ff/random/textTa5d6ff"Tb4b4b4,
Te6edf3data Tff7b72= Tff7b72NoneTb4b4b4,
Te6edf3response_callback Tff7b72= Te6edf3got_responseTb4b4b4,
Te6edf3failed_callback Tff7b72= Te6edf3request_failed
Tb4b4b4)


Tff7b72except Tf85149Exception Tff7b72as Te6edf3eTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffError while sending request over the link: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3eTb4b4b4)Tb4b4b4)
Te6edf3should_quit Tff7b72= Tff7b72True
Te6edf3server_linkTff7b72.Td2a8ffteardownTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffgot_responseTb4b4b4(Te6edf3request_receiptTb4b4b4)Tb4b4b4:
Te6edf3request_id Tff7b72= Te6edf3request_receiptTff7b72.Td2a8ffrequest_id
Te6edf3response Tff7b72= Te6edf3request_receiptTff7b72.Td2a8ffresponse

Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffGot response for request Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3request_idTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff: Ta5d6ff"Tff7b72+Tffa657strTb4b4b4(Te6edf3responseTb4b4b4)Tb4b4b4)

Tff7b72def Td2a8ffrequest_receivedTb4b4b4(Te6edf3request_receiptTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe request Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3request_receiptTff7b72.Td2a8ffrequest_idTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff was received by the remote peer.Ta5d6ff"Tb4b4b4)

Tff7b72def Td2a8ffrequest_failedTb4b4b4(Te6edf3request_receiptTb4b4b4)Tb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe request Ta5d6ff"Tff7b72+Te6edf3RNSTff7b72.Td2a8ffprettyhexrepTb4b4b4(Te6edf3request_receiptTff7b72.Td2a8ffrequest_idTb4b4b4)Tff7b72+Ta5d6ff"Ta5d6ff failed.Ta5d6ff"Tb4b4b4)


T8b949e# This function is called when a link
T8b949e# has been established with the server
Tff7b72def Td2a8fflink_establishedTb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4:
T8b949e# We store a reference to the link
T8b949e# instance for later use
Tff7b72global Te6edf3server_link
Te6edf3server_link Tff7b72= Te6edf3link

T8b949e# Inform the user that the server is
T8b949e# connected
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffLink established with server, hit enter to perform a request, or type in Tffea00\"Ta5d6ffquitTffea00\"Ta5d6ff to quitTa5d6ff"Tb4b4b4)

T8b949e# When a link is closed, we'll inform the
T8b949e# user, and exit the program
Tff7b72def Td2a8fflink_closedTb4b4b4(Te6edf3linkTb4b4b4)Tb4b4b4:
Tff7b72if Te6edf3linkTff7b72.Td2a8ffteardown_reason Tff7b72== Te6edf3RNSTff7b72.Td2a8ffLinkTff7b72.Td2a8ffTIMEOUTTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe link timed out, exiting nowTa5d6ff"Tb4b4b4)
Tff7b72elif Te6edf3linkTff7b72.Td2a8ffteardown_reason Tff7b72== Te6edf3RNSTff7b72.Td2a8ffLinkTff7b72.Td2a8ffDESTINATION_CLOSEDTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffThe link was closed by the server, exiting nowTa5d6ff"Tb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3RNSTff7b72.Td2a8fflogTb4b4b4(Ta5d6ff"Ta5d6ffLink closed, exiting nowTa5d6ff"Tb4b4b4)
Te6edf3timeTff7b72.Td2a8ffsleepTb4b4b4(T79c0ff1.5Tb4b4b4)
Te6edf3sysTff7b72.Td2a8ffexitTb4b4b4(T79c0ff0Tb4b4b4)


T8b949e##########################################################
T8b949e#### Program Startup #####################################
T8b949e##########################################################

T8b949e# This part of the program runs at startup,
T8b949e# and parses input of from the user, and then
T8b949e# starts up the desired program mode.
Tff7b72if Tff7b72__name__ Tff7b72== Ta5d6ff"Ta5d6ff__main__Ta5d6ff"Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3parser Tff7b72= Te6edf3argparseTff7b72.Td2a8ffArgumentParserTb4b4b4(Te6edf3descriptionTff7b72=Ta5d6ff"Ta5d6ffSimple request/response exampleTa5d6ff"Tb4b4b4)

Te6edf3parserTff7b72.Td2a8ffadd_argumentTb4b4b4(
Ta5d6ff"Ta5d6ff-sTa5d6ff"Tb4b4b4,
Ta5d6ff"Ta5d6ff--serverTa5d6ff"Tb4b4b4,
Te6edf3actionTff7b72=Ta5d6ff"Ta5d6ffstore_trueTa5d6ff"Tb4b4b4,
Te6edf3helpTff7b72=Ta5d6ff"Ta5d6ffwait for incoming requests from clientsTa5d6ff"
Tb4b4b4)

Te6edf3parserTff7b72.Td2a8ffadd_argumentTb4b4b4(
Ta5d6ff"Ta5d6ff--configTa5d6ff"Tb4b4b4,
Te6edf3actionTff7b72=Ta5d6ff"Ta5d6ffstoreTa5d6ff"Tb4b4b4,
Te6edf3defaultTff7b72=Tff7b72NoneTb4b4b4,
Te6edf3helpTff7b72=Ta5d6ff"Ta5d6ffpath to alternative Reticulum config directoryTa5d6ff"Tb4b4b4,
Tffa657typeTff7b72=Tffa657str
Tb4b4b4)

Te6edf3parserTff7b72.Td2a8ffadd_argumentTb4b4b4(
Ta5d6ff"Ta5d6ffdestinationTa5d6ff"Tb4b4b4,
Te6edf3nargsTff7b72=Ta5d6ff"Ta5d6ff?Ta5d6ff"Tb4b4b4,
Te6edf3defaultTff7b72=Tff7b72NoneTb4b4b4,
Te6edf3helpTff7b72=Ta5d6ff"Ta5d6ffhexadecimal hash of the server destinationTa5d6ff"Tb4b4b4,
Tffa657typeTff7b72=Tffa657str
Tb4b4b4)

Te6edf3args Tff7b72= Te6edf3parserTff7b72.Td2a8ffparse_argsTb4b4b4(Tb4b4b4)

Tff7b72if Te6edf3argsTff7b72.Td2a8ffconfigTb4b4b4:
Te6edf3configarg Tff7b72= Te6edf3argsTff7b72.Td2a8ffconfig
Tff7b72elseTb4b4b4:
Te6edf3configarg Tff7b72= Tff7b72None

Tff7b72if Te6edf3argsTff7b72.Td2a8ffserverTb4b4b4:
Te6edf3serverTb4b4b4(Te6edf3configargTb4b4b4)
Tff7b72elseTb4b4b4:
Tff7b72if Tb4b4b4(Te6edf3argsTff7b72.Td2a8ffdestination Tff7b72== Tff7b72NoneTb4b4b4)Tb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ff"Tb4b4b4)
Te6edf3parserTff7b72.Td2a8ffprint_helpTb4b4b4(Tb4b4b4)
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ff"Tb4b4b4)
Tff7b72elseTb4b4b4:
Te6edf3clientTb4b4b4(Te6edf3argsTff7b72.Td2a8ffdestinationTb4b4b4, Te6edf3configargTb4b4b4)

Tff7b72except Tf85149KeyboardInterruptTb4b4b4:
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ff"Tb4b4b4)
Te6edf3sysTff7b72.Td2a8ffexitTb4b4b4(T79c0ff0Tb4b4b4)


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────